package org.linlinjava.litemall.admin.web2.goods;

import com.github.pagehelper.PageHelper;
import io.swagger.annotations.*;
import org.linlinjava.litemall.admin.web2.BaseController;
import org.linlinjava.litemall.admin.web2.goods.req.*;
import org.linlinjava.litemall.admin.web2.goods.resp.*;
import org.linlinjava.litemall.core.util.R;
import org.linlinjava.litemall.core.util.Util;
import org.linlinjava.litemall.db.dao.*;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.enumeration.Const;
import org.linlinjava.litemall.db.util.Str;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 商品管理
 */
@Api("商品管理[分类查询、商品新增和更新]")
@RestController
@RequestMapping("/goods/")
public class AGoodsController extends BaseController {


    @ApiOperation(value = "获取分类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "onlyParent", value = "是否只要父节点[true、false，默认false]", paramType = "query")
    })
    @GetMapping("/catalogList")
    public Object catalogList(@RequestParam(defaultValue = "false") Boolean onlyParent) {
        List<TCatalog> all = catalogMapper.selectByExample(TCatalogExample.newAndCreateCriteria().andDeletedEqualTo(Boolean.FALSE).when(onlyParent, c -> c.andPidIsNull()).example());
        List<Resp1> res = Util.aList(all.size());
        all.forEach(c -> {
            if (c.getId() >= 0) {
                Resp1 r = new Resp1();
                r.setcId(c.getId());
                r.setName(c.getName());
                r.setShowGoodsNum(c.getShowGoodsNum());
                res.add(r);
            }
        });
        return R.ok(res);
    }

    @ApiOperation(value = "分类授权")
    @PostMapping("/authCatalog")
    public Object authCatalog(@RequestBody GReq4 req) {
        Integer id = req.getId();
        Boolean auth = req.getAuth();
        TCatalog catalog = catalogMapper.selectByPrimaryKey(id);
        switch (req.getField()) {
            case "wxShow":
                catalog.setWxShow(auth);
                break;
            case "directShopAuth":
                catalog.setDirectShopAuth(auth);
                break;
            case "franshiseShopAuth":
                catalog.setFranshiseShopAuth(auth);
                break;
            case "franshise2ShopAuth":
                catalog.setFranshise2ShopAuth(auth);
                break;
        }
        catalogMapper.updateByPrimaryKey(catalog);
        return R.ok();
    }


    @ApiOperation(value = "分类删除")
    @GetMapping("/delCatalog")
    public Object delCatalog(@RequestParam Integer cId) {
        log.info("分类删除[id={}]", cId);
        if (cId == -1 || cId == -2)
            return R.fail("拼团和秒杀无法删除");
        TCatalog catalog = catalogMapper.selectByPrimaryKey(cId);
        List<TCatalog> tCatalogs = catalogMapper.selectByExample(TCatalogExample.newAndCreateCriteria().andPidEqualTo(cId).example());

        List<TCatalog> catalogs = Util.aList(tCatalogs);
        catalogs.add(catalog);
        catalogs.forEach(c -> {
            c.setDeleted(true);
            catalogMapper.updateByPrimaryKey(c);
        });
        return R.ok();
    }


    private Map<Integer, String> getCatalogMap() {
        List<TCatalog> all = catalogMapper.selectByExample(TCatalogExample.newAndCreateCriteria().andDeletedEqualTo(Boolean.FALSE).example());
        Map<Integer, String> map = Util.hMap();
        all.forEach(c -> map.put(c.getId(), c.getName()));
        return map;
    }

    @ApiOperation(value = "分类管理页面数据")
    @GetMapping("/catalogIndex")
    @ApiResponses({@ApiResponse(response = GResp3.class, message = "正常响应", code = 200)
    })
    public Object catalogIndex() {
        List<TCatalog> all = catalogMapper.selectByExample(TCatalogExample.newAndCreateCriteria().andDeletedEqualTo(Boolean.FALSE).example());
        Map<Integer, GResp3> map = Util.hMap();
        List<GResp3> res = Util.aList(all.size());
        log.info("填充一级分类");
        all.forEach(c -> {
            if (c.getPid() == null) {
                GResp3 vo = new GResp3(c);
                res.add(vo);
                map.put(c.getId(), vo);
            }
        });
        log.info("填充二级分类");
        all.forEach(c -> {
            if (c.getPid() != null) {
                GResp3 vo = map.get(c.getPid());
                if (vo != null) {
                    vo.addSub(new GResp3(c));
                }
            }
        });
        return R.ok(res);
    }

    @ApiOperation(value = "保存分类[带id为修改，无则新增]")
    @PostMapping("/addCatalog")
    public Object addCatalog(@RequestBody GReq2 req) {
        TCatalog entity = GReq2.getEntity(req);
        if (req.getId() == null) {
            log.info("新增分类");
            entity.setCreatedTime(LocalDateTime.now());
            entity.setPid(req.getpId());
            catalogMapper.insert(entity);
        } else {
            log.info("修改分类");
            entity.setCreatedTime(null);
            catalogMapper.updateByPrimaryKeySelective(entity);
        }
        return R.ok();
    }

// #######################################################################################################################


    @ApiOperation(value = "商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "商品状态:[-1-全部、0-上架中、1-定时预售、2-仓库]", paramType = "query"),
            @ApiImplicitParam(name = "cId", value = "分类id", paramType = "query"),
            @ApiImplicitParam(name = "goodsName", value = "商品名称", paramType = "query"),
            @ApiImplicitParam(name = "isTimely", value = "是否及时达[0-否、1-是]", paramType = "query"),
            @ApiImplicitParam(name = "page", paramType = "query"),
            @ApiImplicitParam(name = "size", paramType = "query")
    })
    @GetMapping("/list")
    @ApiResponses({@ApiResponse(response = GResp2.class, message = "正常响应", code = 200)
    })
    public Object list(@RequestParam(defaultValue = "-1") Integer status,
                       @RequestParam(required = false) Integer cId,
                       @RequestParam(required = false) String goodsName,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer size,
                       @RequestParam(defaultValue = "0") Integer isTimely) {

        TGoodsExample query = TGoodsExample.newAndCreateCriteria()
                .when(status >= 0, c -> c.andStatusEqualTo(status))
                .when(getCurrentShopId() != null, c -> c.andShopIdEqualTo(getCurrentShopId()))
                .when(cId != null, c -> c.andCIdEqualTo(cId))
                .when(isTimely == 1, c -> c.andTypeEqualTo(Const.GOODS_TYPE.TIMELY))   //及时达
                .when(isTimely == 0, c -> c.andTypeEqualTo(Const.GOODS_TYPE.NONE))   //商品列表
                .when(!Str.isEmpty(goodsName), c -> c.andMainTitleLike(Str.toLike(goodsName)))
                .andDeletedEqualTo(Boolean.FALSE)
                .example().orderBy("created_time desc");
        PageHelper.startPage(page, size);
        List<TGoods> tGoods = goodsMapper.selectByExample(query);
        List<GResp2> resList = Util.aList(tGoods.size());
        Map<Integer, String> catalogMap = getCatalogMap();
        tGoods.forEach(g -> {
            GResp2 vo = new GResp2(g);
            vo.setCatalog(catalogMap.get(g.getcId()));
            resList.add(vo);
        });
        return R.okList(resList, tGoods);
    }

    @ApiOperation(value = "商品回收站")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "goodsName", value = "商品名称", paramType = "query"),
            @ApiImplicitParam(name = "page", paramType = "query"),
            @ApiImplicitParam(name = "size", paramType = "query")
    })
    @GetMapping("/recycleBinList")
    @ApiResponses({@ApiResponse(response = GResp7.class, message = "正常响应", code = 200)
    })
    public Object recycleBinList(
            @RequestParam(required = false) String goodsName,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {

        TGoodsExample query = TGoodsExample.newAndCreateCriteria()
                .when(!Str.isEmpty(goodsName), c -> c.andMainTitleLike(Str.toLike(goodsName)))
                .andDeletedEqualTo(Boolean.TRUE)
                .example().orderBy("created_time desc");
        PageHelper.startPage(page, size);

        List<TGoods> tGoods = goodsMapper.selectByExample(query);
        List<GResp7> resList = Util.aList(tGoods.size());
        Map<Integer, String> catalogMap = getCatalogMap();
        tGoods.forEach(g -> {
            GResp7 vo = new GResp7(g);
            vo.setCatalog(catalogMap.get(g.getcId()));
            resList.add(vo);
        });
        return R.okList(resList, tGoods);
    }

    @ApiOperation(value = "还原商品")
    @PostMapping("restore")
    public Object restore(@RequestBody GReq7 req) {
        log.info("批量还原商品");
        List<Integer> ids = Str.idsStrToListInt(req.getIds());
        for (Integer id : ids) {
            TGoods goods = goodsMapper.selectByPrimaryKey(id);
            goods.setDeleted(Boolean.FALSE);
            goodsMapper.updateByPrimaryKeySelective(goods);
        }
        return R.ok(ids.size());
    }

    @ApiOperation(value = "团购商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "query"),
            @ApiImplicitParam(name = "cId", value = "分类id", paramType = "query"),
            @ApiImplicitParam(name = "goodsName", value = "商品名称", paramType = "query"),
            @ApiImplicitParam(name = "page", paramType = "query"),
            @ApiImplicitParam(name = "size", paramType = "query")
    })
    @GetMapping("/groupList")
    @ApiResponses({@ApiResponse(response = GResp4.class, message = "正常响应", code = 200)
    })
    public Object groupList(@RequestParam(required = false) Integer cId,
                            @RequestParam(required = false) String goodsName,
                            @RequestParam(defaultValue = "1") Integer page,
                            @RequestParam(defaultValue = "10") Integer size) {

        TGoodsExample query = TGoodsExample.newAndCreateCriteria()
                .andTypeEqualTo(Const.GOODS_TYPE.GROUP)
                .when(getCurrentShopId() != null, c -> c.andShopIdEqualTo(getCurrentShopId()))
                .andStatusNotEqualTo(Const.GOODS_STATUS.WAREHOUSE)
                .when(cId != null, c -> c.andCIdEqualTo(cId))
                .when(!Str.isEmpty(goodsName), c -> c.andMainTitleLike(Str.toLike(goodsName)))
                .andDeletedEqualTo(Boolean.FALSE)
                .example().orderBy("created_time desc");
        PageHelper.startPage(page, size);
        List<TGoods> tGoods = goodsMapper.selectByExample(query);
        List<GResp4> resList = Util.aList(tGoods.size());
        Map<Integer, String> catalogMap = getCatalogMap();
        tGoods.forEach(g -> {
            GResp4 vo = new GResp4(g);
            vo.setCatalog(catalogMap.get(g.getcId()));
            resList.add(vo);
        });
        return R.okList(resList, tGoods);
    }


    @ApiOperation(value = "秒杀商品列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", paramType = "query"),
            @ApiImplicitParam(name = "cId", value = "分类id", paramType = "query"),
            @ApiImplicitParam(name = "goodsName", value = "商品名称", paramType = "query"),
            @ApiImplicitParam(name = "page", paramType = "query"),
            @ApiImplicitParam(name = "size", paramType = "query")
    })
    @GetMapping("/seckillList")
    @ApiResponses({@ApiResponse(response = GResp5.class, message = "正常响应", code = 200)
    })
    public Object seckillList(@RequestParam(required = false) Integer cId,
                              @RequestParam(required = false) String goodsName,
                              @RequestParam(defaultValue = "1") Integer page,
                              @RequestParam(defaultValue = "10") Integer size) {

        TGoodsExample query = TGoodsExample.newAndCreateCriteria()
                .andTypeEqualTo(Const.GOODS_TYPE.SECKILL)
                .when(getCurrentShopId() != null, c -> c.andShopIdEqualTo(getCurrentShopId()))
                .andStatusEqualTo(Const.GOODS_STATUS.NONE)
                .when(cId != null, c -> c.andCIdEqualTo(cId))
                .when(!Str.isEmpty(goodsName), c -> c.andMainTitleLike(Str.toLike(goodsName)))
                .andDeletedEqualTo(Boolean.FALSE)
                .example().orderBy("id desc");
        PageHelper.startPage(page, size);
        List<TGoods> tGoods = goodsMapper.selectByExample(query);
        List<GResp5> resList = Util.aList(tGoods.size());
        Map<Integer, String> catalogMap = getCatalogMap();
        tGoods.forEach(g -> {
            GResp5 vo = new GResp5(g);
            vo.setCatalog(catalogMap.get(g.getcId()));
            resList.add(vo);
        });
        return R.okList(resList, tGoods);
    }

    @ApiOperation(value = "商品审核列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", paramType = "query"),
            @ApiImplicitParam(name = "size", paramType = "query")
    })
    @GetMapping("/applyList")
    @ApiResponses({@ApiResponse(response = GResp6.class, message = "正常响应", code = 200)
    })
    public Object applyList(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) {
        PageHelper.startPage(page, size);
        List<TGoodsApply> list = goodsApplyMapper.selectByExample(TGoodsApplyExample
                .newAndCreateCriteria().andDeletedEqualTo(Boolean.FALSE).example().orderBy("created_time desc"));
        List<GResp6> resList = Util.aList(list.size());
        Map<Integer, String> catalogMap = getCatalogMap();
        list.forEach(g -> {
            GResp6 vo = new GResp6(g);
            vo.setCatalog(catalogMap.get(g.getcId()));
            resList.add(vo);
        });
        return R.okList(resList, list);
    }

    @ApiOperation(value = "商品审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", paramType = "query"),
            @ApiImplicitParam(name = "opt", value = "通过true|失败false", paramType = "query")
    })
    @GetMapping("/applyOk")
    @ApiResponses({@ApiResponse(response = GResp6.class, message = "正常响应", code = 200)
    })
    public Object applyOk(@RequestParam String id, @RequestParam Boolean opt) {
        log.info("商品审核,参数:[{}]", opt);
        String[] _ids = id.split(",");
        for (String _idStr : _ids) {
            Integer _id = Integer.parseInt(_idStr);
            TGoodsApply goodsApply = goodsApplyMapper.selectByPrimaryKey(_id);
            if (opt) {
                Integer tmpId = goodsApply.getTmpId();
                TGoodsTmp tGoodsTmp = goodsTmpMapper.selectByPrimaryKey(tmpId);
                TGoods goods = new TGoods();
                Util.copy(tGoodsTmp, goods);
                goods.setId(null);
                goods.setType(Const.GOODS_TYPE.NONE);
                goodsMapper.insert(goods);
                log.info("判断是否有活动商品");
                if (tGoodsTmp.getActivityStatus() == Const.ACTIVITY_STATUS.GROUP) {
                    log.info("有拼团商品，复制一份新的");
                    TGoods newGoods = Util.getNewGoods(goods);
                    newGoods.setType(Const.GOODS_TYPE.GROUP);
                    newGoods.setCurrentPrice(tGoodsTmp.getActivityPrice());
                    goodsMapper.insert(newGoods);
                }
                if (tGoodsTmp.getActivityStatus() == Const.ACTIVITY_STATUS.SECKILL) {
                    log.info("有拼团商品，复制一份新的");
                    TGoods newGoods = Util.getNewGoods(goods);
                    newGoods.setType(Const.GOODS_TYPE.SECKILL);
                    newGoods.setCurrentPrice(tGoodsTmp.getActivityPrice());
                    goodsMapper.insert(newGoods);
                }
            }
            goodsApply.setDeleted(Boolean.TRUE);
            goodsApplyMapper.updateByPrimaryKey(goodsApply);
        }
        return R.ok("成功");
    }


    @ApiOperation(value = "批量操作")
    @PostMapping("/batchOpt")
    public Object batchOpt(@RequestBody GReq5 req) {
        log.info("批量操作");
        List<Integer> ids = Str.idsStrToListInt(req.getIds());
        for (Integer id : ids) {
            TGoods goods = goodsMapper.selectByPrimaryKey(id);
            goods.setCommission(req.getCommission());
            goods.setCurrentPrice(goods.getCurrentPrice().subtract(new BigDecimal(req.getAmount())));
            goods.setDailyLimit(req.getDailyNum());
            goodsMapper.updateByPrimaryKeySelective(goods);
        }
        return R.ok(ids.size());
    }

    @ApiOperation(value = "批量上架或下架")
    @PostMapping("/batchUpOrDown")
    public Object batchUpOrDown(@RequestBody GReq3 req) {
        log.info("批量上架或下架");
        String[] ids = req.getIds().split(",");
        Integer status = req.getUpOrDown() ? Const.GOODS_STATUS.NONE : Const.GOODS_STATUS.WAREHOUSE;
        for (String id : ids) {
            int i = Integer.parseInt(id);
            TGoods goods = goodsMapper.selectByPrimaryKey(i);
            goods.setStatus(status);
            goodsMapper.updateByPrimaryKeySelective(goods);
        }
        return R.ok();
    }

    @ApiOperation(value = "批量设置及时达")
    @PostMapping("/batchTimely")
    @Transactional
    public Object batchTimely(@RequestBody GReq7 req) {
        log.info("批量设置及时达");
        List<Integer> ids = Str.idsStrToListInt(req.getIds());
        int res = ids.size();
        for (Integer id : ids) {
            log.info("查询原商品并且复制新的商品成为及时达");
            TGoods goods = goodsMapper.selectByPrimaryKey(id);
            TGoodsExtend rec = goodsExtendMapper.selectOneByExample(TGoodsExtendExample.newAndCreateCriteria().andPIdEqualTo(id).example());
            if(rec == null){
                TGoods timeLyGoods = Util.getNewGoods(goods);
                timeLyGoods.setStatus(Const.GOODS_STATUS.NONE);
                timeLyGoods.setType(Const.GOODS_TYPE.TIMELY);
                goodsMapper.insert(timeLyGoods);
                log.info("插入商品扩展信息");
                rec = new TGoodsExtend();
                rec.setgId(timeLyGoods.getId());
                rec.setpId(id);
                rec.setCreatedTime(LocalDateTime.now());
                rec.setType(Const.GOODS_TYPE.TIMELY);
                goodsExtendMapper.insert(rec);
            }

        }
        return R.ok(res);
    }



    @ApiOperation(value = "保存秒杀")
    @PostMapping("/saveSeckill")
    public Object saveSeckill(@RequestBody GReq6 req) {
        log.info("保存秒杀");
        Integer id = req.getId();
        TGoods tGoods = goodsMapper.selectByPrimaryKey(id);
        if (tGoods == null) {
            return R.fail("没有商品,id参数错误");
        }
        if (tGoods.getType() != Const.GOODS_TYPE.SECKILL) {
            log.info("复制新的秒杀商品");
            TGoods seckillGoods = Util.getNewGoods(tGoods);
            req.setGoods(seckillGoods);
            seckillGoods.setType(Const.GOODS_TYPE.SECKILL);
            seckillGoods.setCreatedTime(LocalDateTime.now());
            goodsMapper.insert(seckillGoods);
        } else {
            req.setGoods(tGoods);
            goodsMapper.updateByPrimaryKeySelective(tGoods);
        }
        return R.ok();
    }

    @ApiOperation(value = "保存拼团")
    @PostMapping("/saveGroup")
    public Object saveGroup(@RequestBody GReq6_ req) {
        log.info("保存拼团");
        Integer id = req.getId();
        TGoods tGoods = goodsMapper.selectByPrimaryKey(id);
        if (tGoods == null) {
            return R.fail("没有商品,id参数错误");
        }
        if (tGoods.getType() != Const.GOODS_TYPE.GROUP) {
            log.info("复制新的拼团商品");
            TGoods groupGoods = Util.getNewGoods(tGoods);
            req.setGoods(groupGoods);
            groupGoods.setType(Const.GOODS_TYPE.GROUP);
            groupGoods.setCreatedTime(LocalDateTime.now());
            goodsMapper.insert(groupGoods);
        } else {
            req.setGoods(tGoods);
            goodsMapper.updateByPrimaryKeySelective(tGoods);
        }
        return R.ok();
    }

    @ApiOperation(value = "保存商品[带id为修改，无则新增]")
    @PostMapping("/save")
    public Object save(@RequestBody GReq1 req) {
        TGoods goods = GReq1.getTGoods(req);
        Integer id = req.getId();
        if (id == null) {
            goods.setShopId(getCurrentShopId());
            goods.setCreatedTime(LocalDateTime.now());
            goodsMapper.insert(goods);
        } else {
            TGoods oldGoods = goodsMapper.selectByPrimaryKey(id);
            if (oldGoods == null)
                return R.fail("商品不存在");
            goods.setShopId(oldGoods.getShopId());
            goods.setId(oldGoods.getId());
            goods.setCreatedTime(oldGoods.getCreatedTime());
            goodsMapper.updateByPrimaryKeySelective(goods);
        }
        return R.ok();
    }

    @ApiOperation(value = "删除商品[带id]")
    @PostMapping("/delete")
    public Object delete(@RequestBody GReq7 req) {
        log.info("批量删除商品");
        List<Integer> ids = Str.idsStrToListInt(req.getIds());
        for (Integer id : ids) {
            TGoods goods = goodsMapper.selectByPrimaryKey(id);
            goods.setDeleted(Boolean.TRUE);
            goodsMapper.updateByPrimaryKeySelective(goods);
        }
        return R.ok(ids.size());
    }

    @ApiOperation(value = "商品详情")
    @GetMapping("/get")
    @ApiResponses({@ApiResponse(response = GReq1.class, message = "正常响应", code = 200)
    })
    public Object get(@RequestParam Integer id) {
        TGoods entity = goodsMapper.selectByPrimaryKey(id);
        if (entity == null)
            return R.fail("商品不存在");
        return R.ok(GReq1.getDTO(entity));
    }


    @Autowired
    private TGoodsExtendMapper goodsExtendMapper;
    @Autowired
    TCatalogMapper catalogMapper;
    @Autowired
    TGoodsMapper goodsMapper;
    @Autowired
    TGoodsApplyMapper goodsApplyMapper;
    @Autowired
    private TGoodsTmpMapper goodsTmpMapper;
    static Logger log = LoggerFactory.getLogger(AGoodsController.class);
}
